package com.bangyu.monitor.core.util;

import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Auther: zhangxue
 * @Date: 19/6/25 21:19
 * @Description:
 */
public class HttpClientUtil {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    private static final String defaultCharset = "UTF-8";

    private static CloseableHttpClient httpClient = null;
    private static RequestConfig requestConfig = null;


    static {
        int maxConnTotal = 2000;
        int maxConnPerRoute = 200;
        int connRequestTimeOut = 5000;
        int soTimeOut = 5000;
        int connectTimeOut = 5000;

        requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(connRequestTimeOut)
                .setConnectTimeout(connectTimeOut)
                .setSocketTimeout(soTimeOut)
                .build();
        httpClient = HttpClientBuilder
                .create()
                .setMaxConnTotal(maxConnTotal)
                .setMaxConnPerRoute(maxConnPerRoute)
                .setDefaultSocketConfig(SocketConfig.custom().setSoKeepAlive(true).setSoReuseAddress(true).setSoTimeout(soTimeOut).build())
                .setDefaultRequestConfig(requestConfig)
                .build();

    }

    public static String getQueryUrl(String url, Map<String, String> param) {
        String formatUrl = null;
        // 创建参数队列
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        if (MapUtils.isNotEmpty(param)) {
            for (Map.Entry<String, String> entry : param.entrySet()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            try {
                formatUrl = url + "?" + EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairs, defaultCharset));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            formatUrl = url;
        }

        return formatUrl;
    }


    public static String sendGet(String url, Map<String, String> param) {
        String formatUrl;
        long startTime = 0;
        long endTime;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        try {
            formatUrl = getQueryUrl(url, param);
            HttpGet httpGet = new HttpGet(formatUrl);
            startTime = System.currentTimeMillis();
            response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK != statusCode) {
                logger.warn("Method : HttpClientUtils | sendGet error  status code = {}  url = {}", statusCode, formatUrl);
                return null;
            }
            entity = response.getEntity();
            return EntityUtils.toString(entity, defaultCharset);
        } catch (IOException e) {
            endTime = System.currentTimeMillis();
            logger.warn("Method : HttpClientUtils |  sendGet error time ==={}  url === {}", (endTime - startTime), url, e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                EntityUtils.consumeQuietly(entity);
            } catch (IOException e) {
                logger.warn("Method : HttpClientUtils | sendGet resp.close() error，url = " + url, e);
            }
        }

        return null;

    }

    public static String sendPost(String url, Map<String, String> param) {
        long startTime = 0;
        long endTime;
        CloseableHttpResponse resp = null;
        HttpEntity entity = null;
        try {
            HttpPost httpPost = new HttpPost(url);

            // 创建参数队列
            List<NameValuePair> nameValuePairs = new ArrayList<>();
            UrlEncodedFormEntity urlEncodedFormEntity = null;
            if(param != null){
                for (Map.Entry<String, String> entry : param.entrySet()) {
                    nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairs, defaultCharset);
                httpPost.setEntity(urlEncodedFormEntity);
            }


            startTime = System.currentTimeMillis();
            resp = httpClient.execute(httpPost);
            int statusCode = resp.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK != statusCode && HttpStatus.SC_ACCEPTED != statusCode && HttpStatus.SC_CREATED != statusCode) {
                logger.error("Method : HttpClientUtils | sendPost  status code = {}  url = {}", statusCode, url);
            }
            entity = resp.getEntity();
            return EntityUtils.toString(entity, defaultCharset);
        } catch (IOException e) {
            endTime = System.currentTimeMillis();
            logger.error("Method : HttpClientUtils |  sendPost error time ==={}  url === {}", (endTime - startTime), url, e);
        } finally {
            try {
                if (resp != null) {
                    resp.close();
                }
                EntityUtils.consumeQuietly(entity);
            } catch (IOException e) {
                logger.error("Method : HttpClientUtils | sendPost resp.close() error，url = {}", url, e);
            }
        }

        return null;
    }

    public static void main(String[] args) {
        String url = "http://10.171.36.250:8001/openapi/orderpick/complete";
        Map<String, String> paramMap = Maps.newHashMap();
        paramMap.put("order_id", "399");
        String queryUrl = HttpClientUtil.getQueryUrl(url, paramMap);
        System.out.println(queryUrl);
        String response = HttpClientUtil.sendGet(url, paramMap);
        System.out.println(response);
    }

}
